/*
 * Copyright (c) 2022-2023 cetcclout Co., Ltd All rights reserved.
 * Sensor Adapter is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package com.cetccloud.cimp.adapter.handler.netty;

import cn.hutool.json.JSONObject;

import com.cetccloud.cimp.adapter.cache.ClientDeviceCache;
import com.cetccloud.cimp.adapter.datasource.redis.RedisService;
import com.cetccloud.cimp.adapter.handler.DataContextValue;
import com.cetccloud.cimp.adapter.handler.abstracts.AbstractAuthHandler;
import com.cetccloud.cimp.common.util.SensorStringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.netty.channel.ChannelHandlerContext;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.nio.Buffer;

/**
 * @author
 * @apiNote 设备注册校验
 * @date 2023/3/3 10:58
 */
@Component("tcpAuthHandler")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TcpAuthHandler extends AbstractAuthHandler {
    private static final InternalLogger logger = InternalLoggerFactory.getInstance(TcpAuthHandler.class);

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    
    @Autowired
    private RedisService redisService;

    /**
     * 设备数据解析
     */
    @Override
    public String auth(Buffer buffer, Object context) {
    	String deviceId = null;
    	try {
			JSONObject jsonObject = OBJECT_MAPPER.readValue((byte[]) buffer.array(), JSONObject.class);
			deviceId = jsonObject.getStr("deviceId");
		} catch (Exception e) {
			((ChannelHandlerContext) context).channel().close();
			e.printStackTrace();
		}
    	ChannelHandlerContext ctx = ((ChannelHandlerContext) context);
    	if(!verifyRegister(ctx, deviceId)) {
    		deviceId = null;
    	}

        return deviceId;
    }
    
    /**
     * 设备注册信息验证
     */
    private boolean verifyRegister(ChannelHandlerContext context, String deviceId) {

        ChannelHandlerContext ctx = context;
        // exist deviceId
        String memoryDeviceId = ClientDeviceCache.getDtuId(ctx.channel()).trim();

        if(SensorStringUtils.isEmpty(memoryDeviceId)){
            // 判断监控仪是否合法存在
            if(redisService.hasKey(String.format(DataContextValue.DEVICE_KEY, deviceId))){
                ClientDeviceCache.addChannel(deviceId, ctx.channel());
                //更新设备状态
                redisService.sSet(DataContextValue.DTU_STATUS_KEY, deviceId);
                logger.info("成功初始化，注册链接 ： " + deviceId);
                return true;
            }else{
                logger.error("监控仪信息非法，请先在平台注册监控仪信息！");
                ctx.channel().close();
            }
            return false;
        }else {
            return true;
        }
    }

    /**
     * 签名以供设备识别
     */
    @Override
    public Buffer sign(Buffer buffer, String dtuId) {
        //todo 签名加密
        logger.info("数据出站的签名！！！");
        return buffer;
    }
}
